import {Component, EventEmitter, Input, OnInit, Output, TemplateRef, ViewChild} from '@angular/core';
import {BaseTreeService} from '@sb/base/core/service/base-tree.service';
import {BaseNzTreeNodeOptions, BaseTreeComponent, Page, ReturnForm} from '@sb/base';
import {NzMessageService} from 'ng-zorro-antd';
import {SysRegionTreeNodeService} from '../service/sys-region-tree-node.service';
import {SysRegionTreeNode} from '../entity/sys-region-tree-node';
import {Observable, of} from 'rxjs';
import {NzTreeNode} from 'ng-zorro-antd/core/tree/nz-tree-base-node';
import {STData} from '@delon/abc';
import {BaseTreeSearchConfig} from '@sb/base/core/entity/base-tree-search-config';

@Component({
    selector: 'sys-region-select-panel',
    templateUrl: './sys-region-select-panel.component.html',
    providers: [{
        provide: BaseTreeService,
        useClass: SysRegionTreeNodeService
    }]
})
export class SysRegionSelectPanelComponent implements OnInit {

    @Input() rootNodeId = '100000';
    @Input() rootNodeName = '行政区域';
    @Input() showSearch = false;

    @Input() deep = -1;

    @Input() showRoot = true;

    @Input() treeNodeTemplate: TemplateRef<{ $implicit: BaseNzTreeNodeOptions<STData>; }>;

    @Input() customSearchByTextMethod: (searchText: string, baseTreeService: BaseTreeService<STData, Page, BaseNzTreeNodeOptions<STData>>) => Observable<ReturnForm<BaseNzTreeNodeOptions<any>[]>>;

    @Input() customGetTreeNodePathMethod: (key: string, baseTreeService: BaseTreeService<STData, Page, BaseNzTreeNodeOptions<STData>>) => Observable<ReturnForm<string[]>>;

    @Input() searchPlaceHolderText;

    @ViewChild('baseTree', {static: false})
    baseTree: BaseTreeComponent;

    typeIcon = {
        root: 'dr:hy-root',
        ORG: 'dr:hy-module',
        DEPT: 'dr:hy-terminal',
        USER: 'dr:user_yw'
    };

    @Output()
    selectNode = new EventEmitter<NzTreeNode>();

    @Input()
    checkable: boolean;

    @Input() afterRegionTreeNodeLoad: (sysRegionTreeNode: SysRegionTreeNode[]) => SysRegionTreeNode[] | Observable<SysRegionTreeNode[]>;

    @Input() leafTreeNodeExpand: (parentId: string, searchConfig?: BaseTreeSearchConfig, maxLevel?: number) => ReturnForm<BaseNzTreeNodeOptions<STData>[]> | Observable<ReturnForm<BaseNzTreeNodeOptions<STData>[]>>;

    constructor(
        private message: NzMessageService) {
    }

    ngOnInit(): void {
    }

    onSelectNode(nzTreeNode: NzTreeNode): void {
        this.selectNode.emit(nzTreeNode);
    }

    reload() {
        this.baseTree.reload();
    }

    reloadNode(nodeId) {
        this.baseTree.reloadNode(nodeId);
    }

    customLoadMethod(parentId: string,
                     searchConfig: any,
                     maxLevel: number,
                     baseTreeService: SysRegionTreeNodeService): Observable<ReturnForm<SysRegionTreeNode[]>> {
        let treeNode: NzTreeNode = this.baseTree.nzTree.getTreeNodeByKey(parentId);

        let deep = 0;

        while (treeNode != null) {
            deep++;
            treeNode = treeNode.parentNode;
        }

        if (deep < this.deep) {
            return new Observable(subscriber => {
                baseTreeService.getNzTree(parentId, searchConfig, maxLevel).subscribe(v => {
                    if (v.success) {
                        if (this.afterRegionTreeNodeLoad) {
                            const re = this.afterRegionTreeNodeLoad(v.message);
                            if (re instanceof Observable) {
                                re.subscribe(vv => {
                                    subscriber.next({
                                        success: true,
                                        message: vv
                                    });
                                });
                                return;
                            } else {
                                v.message = re;
                            }
                        } else if (deep + 1 === this.deep) {
                            for (const one of v.message) {
                                one.children = [];
                                one.loadedChildren = true;
                                one.isLeaf = true;
                            }
                        }
                    }
                    subscriber.next(v);
                });
            });
            // } else if (deep == this.deep) {
            //     if (this.leafTreeNodeExpand) {
            //         return baseTreeService.getNzTree(parentId, searchConfig, maxLevel);
            //     } else {
            //         return new Observable(subscriber => {
            //             baseTreeService.getNzTree(parentId, searchConfig, maxLevel).subscribe(v => {
            //                 if (v.success) {
            //                     for (let one of v.message) {
            //                         one.children = [];
            //                         one.loadedChildren = true;
            //                         one.isLeaf = true;
            //                     }
            //                 }
            //                 subscriber.next(v);
            //             })
            //         })
            //     }
        } else {
            if (this.leafTreeNodeExpand) {
                const result = this.leafTreeNodeExpand(parentId, searchConfig, maxLevel);
                if (result instanceof Observable) {
                    return result;
                } else {
                    return of(result);
                }
            }
            return of({
                success: true,
                status: 200,
                message: []
            });
        }

    }
}


